package com.zdgk.core.licence;

import cn.hutool.json.JSONObject;
import com.zdgk.core.web.common.GlobalExceptionHandler;

import java.io.UnsupportedEncodingException;
import java.net.InetAddress;
import java.net.InterfaceAddress;
import java.net.NetworkInterface;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @className: MachineCodeUtil
 * @description: 机器码（申请码）工具类
 * @author: qiji
 * @createDate: 2022-07-19
 * @version: v1.0
 */
public class MachineCodeUtil {

    /**
    * @return String
    * @author qiji
    * @date 2022/7/19 16:35
    * @Description 生成机器码（申请码）
    */
    public static String createMachineCode() throws Exception {
        JSONObject jsonObject = new JSONObject();
        List<String> macList = getMacList();
        if(macList.size()==0)
            macList.add("");
        jsonObject.put("applyTime",System.currentTimeMillis());
        jsonObject.put("cpu",getCpuId());
        jsonObject.put("mac",macList.get(0));
        jsonObject.put("path",MachineCodeUtil.class.getResource("").getPath());
        try {
            return Base64.getEncoder().encodeToString(jsonObject.toString().getBytes("UTF-8"));
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
            throw new Exception("未知设备");
        }
    }

    /**
    * @return String
    * @author qiji
    * @date 2022/7/19 16:35
    * @Description 获取CPU序列号
    */
    public static String getCpuId() {
        try {
            // linux，windows命令
            String[] linux = {"dmidecode", "-t", "processor", "|", "grep", "'ID'"};
            String[] windows = {"wmic", "cpu", "get", "ProcessorId"};

            // 获取系统信息
            String property = System.getProperty("os.name");
            Process process = Runtime.getRuntime().exec(property.contains("Window") ? windows : linux);
            process.getOutputStream().close();
            Scanner sc = new Scanner(process.getInputStream(), "utf-8");
            sc.next();
            return sc.next();
        } catch (Exception e) {
            return null;
        }
    }


   /**
   * @return List<String>
   * @author qiji
   * @date 2022/7/19 16:36
   * @Description 判断有多个网卡的情况
   */
    public static List<String> getMacList() {
        try {

            Enumeration<NetworkInterface> enumeration = NetworkInterface.getNetworkInterfaces();
            StringBuilder sb = new StringBuilder();
            ArrayList<String> macList = new ArrayList<>();
            while (enumeration.hasMoreElements()) {
                NetworkInterface iface = enumeration.nextElement();
                List<InterfaceAddress> addrs = iface.getInterfaceAddresses();
                for (InterfaceAddress addr : addrs) {
                    // 获取本地IP对象
                    InetAddress ia = addr.getAddress();
                    NetworkInterface network = NetworkInterface.getByInetAddress(ia);
                    if (network == null) {
                        continue;
                    }
                    // 获得网络接口对象（即网卡），并得到mac地址，mac地址存在于一个byte数组中。
                    byte[] mac = network.getHardwareAddress();
                    if (mac == null) {
                        continue;
                    }
                    parseMac(mac, sb);
                    macList.add(sb.toString().toUpperCase());
                    sb.delete(0, sb.length());
                }
            }
            // 去重处理，同一个网卡的ipv4,ipv6得到的mac都是一样的
            if (macList != null && macList.size() > 0) {
                List<String> result = macList.stream().distinct().collect(Collectors.toList());
                return result;
            }

            return null;
        } catch (Exception e) {
            return null;
        }
    }

    /**
    * @description 获取MAC地址
    * @author qiji
    * @date 2022/7/19 16:39
    */
    public static void parseMac(byte[] mac, StringBuilder sb) {
        for (int i = 0; i < mac.length; i++) {
            if (i != 0) {
                sb.append("-");
            }
            // mac[i] & 0xFF 是为了把byte转化为正整数
            String s = Integer.toHexString(mac[i] & 0xFF);
            sb.append(s.length() == 1 ? 0 + s : s);
        }
    }


}
